const lodash = require('lodash')
const loginFns = require('@/puppeteer/common/login')
import { pageFns } from '../utils/pageHelper'
import { Lang } from '@/entities/Constant'
import { PromotionDao } from '@/dao/promotionDao'

const SELECTORS = { "INPUT": ["#prompt-textarea"], "PUBLISH": ["button[data-testid=\"fruitjuice-send-button\"]"], "REGENERATE": ["button[data-testid=\"fruitjuice-send-button\"]"], "CONTENT": ".text-token-text-primary:last-child div[data-message-author-role=\"assistant\"] .markdown" }

async function waitResponseDone(page, selectors) {
    let sels = [...selectors.REGENERATE, 'try']
    await pageFns.deepRetry(sels, page, async (selector, page, setting) => {
        if (selectors.REGENERATE.includes(selector)) {
            await pageFns.waitAttrDidappear(page, selector, "disabled")
        } else {
            await page.reload({ waitUntil: "domcontentloaded" })
        }
        console.log("waitDone", selector, Date.now())
    }, { page: page, timeout: 60 * 1000, wait: 5 * 1000 })
}

async function getElementText(page, selectors) {
    await waitResponseDone(page, selectors)
    console.log("selector", selectors.CONTENT, Date.now())
    await pageFns.delay(1 * 1000)
    await page.waitForSelector(selectors.CONTENT)
    return await page.evaluate((selector) => {
        const e = document.querySelector(selector)
        return e ? e.textContent : null
    }, selectors.CONTENT)
}

async function askQuestion(page, question, selectors) {
    /**
    * @description TYPING INPUT STATUS METHOD
    */
    const textToSend = question.replace(/\n/g, '\t')
    let res = await pageFns.deepRetry(selectors.INPUT, page, async (selector, page) => {
        await page.waitForSelector(selector)
        await page.focus(selector)
        await page.type(selector, textToSend)
        await page.evaluate((selector) => {
            const input = document.querySelector(selector)
            input.value = input.value.replace(/\t/g, '\n')
        }, selector);
    }, { page: page, timeout: 60 * 1000 })
    if (res.err) {
        throw new Error(res.err)
    }
    console.log("waiting for typing", Date.now())
    let sels = [...selectors.PUBLISH, "try"]
    await pageFns.deepRetry(sels, page, async (selector, page) => {
        if (selectors.PUBLISH.includes(selector)) {
            await page.waitForSelector(selector)
            await page.click(selector)
        } else {
            await page.keyboard.press('Enter');
        }
    }, { page: page, timeout: 5 * 1000, wait: 3 * 1000 })
}

const LOGINS = {
    LOGINBTNS: ['.semi-button span::-p-text("Get started")'],
    USERNAMES: ['.semi-input-group .semi-input-wrapper .semi-input'],
    NEXTSTEPS: ['.semi-button .semi-button-content'],
    PASSWORDS: [],
    COMFIRMBTNS: ['.semi-space .semi-button span::-p-text("Next")'],
    UNLOGINFLAGS: ['.semi-input-group .semi-input-wrapper .semi-input']
}

async function goAi(page, task, article, rule) {
    let selectors = JSON.parse(rule.codeRule)
    if (lodash.isEmpty(selectors)) {
        return { err: "找不到发布规则:" + task.id }
    }
    let res = await loginFns.checkLogin(page, task, LOGINS)
    if (res.err) {
        console.log("ai.checkLogin", res)
        return res
    }
    let answers = {}
    for (let promotionId of task.promotionIds) {
        let promotion = await PromotionDao.fetchOne({
            enable: 1,
            id: promotionId,
        })
        if (!promotion) {
            return { err: "找不到对应的提示语：" + promotionId }
        }
        let promotionText = promotion.template
        let lang = Lang.Options().find(item => item.id == promotion.lang)
        if (lodash.isEmpty(lang)) {
            return { err: "找不到对应的语言：" + promotion.lang }
        }
        // 语言替换
        if (promotionText.includes("{{lang}}")) {
            promotionText = promotionText.replaceAll("{{lang}}", lang.name)
        }
        // 关键字替换
        if (promotionText.includes("{{keywords}}") && !lodash.isEmpty(promotion.keywords)) {
            promotionText = promotionText.replaceAll("{{keywords}}", promotion.keywords)
        }
        // 指定字段替换
        let fieldText = "{{" + promotion.sourceField + "}}"
        if (promotionText.includes(fieldText) && !lodash.isEmpty(promotion.sourceField)) {
            promotionText = promotionText.replaceAll(fieldText, article[promotion.sourceField])
        }

        try {
            await askQuestion(page, promotionText, selectors)
            let answer = await getElementText(page, selectors)
            if (lodash.isEmpty(answer)) {
                return { err: "GetElementText找不到回答结果" }
            }
            if (lodash.isEmpty(answers[lang.id])) {
                answers[lang.id] = {}
            }
            if (lodash.isEmpty(promotion.targetField)) {
                answers[lang.id] = lodash.trim(answer)
            } else {
                answers[lang.id][promotion.targetField] = lodash.trim(answer)
            }
        } catch (err) {
            return { err }
        }
    }
    return { err: null, data: answers }
}

export { goAi }